using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using Tomahawk.Runtime.Rendering.Objects;
using Tomahawk.Runtime.Rendering.Materials;
using Tomahawk.Runtime.Rendering;
using Tomahawk.Serialization;
using Tomahawk.Serialization.SerialBoost;
using Tomahawk.Runtime.Resources;

namespace Tomahawk.Runtime.Logic
{
    public class XMaterialMeshComponent : XRenderableComponent
    {
        public XMaterialMeshComponent() : base ()
        {
            //default priority is: Scene
            this.RenderStage = Engine.RenderingStages.Scene;
        }

        #region "Serializable properties"

        private string meshName;
        
        /// <summary>
        /// Indicates the name of the 3D model that will be used
        /// </summary>
        [XmlElement("MeshName")]
        public string MeshName
        {
            get { return meshName; }
            set { meshName = value; }
        }

        private SerializableList<SASMaterial.MaterialDefinition> materials = new SerializableList<SASMaterial.MaterialDefinition>();

        /// <summary>
        /// Allows the model materials to be overriden by XEngine materials
        /// </summary>
        [XmlElement("Materials")]
        public SerializableList<SASMaterial.MaterialDefinition> Materials
        {
            get { return materials; }
            set { materials = value; }
        }

        protected RenderManager.Layers layer = RenderManager.Layers.Standard;

        /// <summary>
        /// Indicates the render layer this mesh belongs to
        /// </summary>
        [XmlElement("RenderLayer")]
        public RenderManager.Layers Layer 
        { 
            get { return layer; } 
            set { layer = value; } 
        }

        protected string renderGroups = "Color";

        /// <summary>
        /// Indicates the render modes this mesh belongs to
        /// </summary>
        [XmlElement("RenderGroups")]
        public string RenderGroups
        {
            get { return renderGroups; }
            set 
            { 
                renderGroups = value;
                if (SceneNode != null)
                {
                    SceneNode.RenderGroupNames = this.RenderGroups;
                }
            }
        }

        [XmlAttribute("pool")]
        public ResourceManager.ResourcePool ResourcePool = ResourceManager.ResourcePool.GameState;

        #endregion

        protected MaterialMesh meshModel;

        /// <summary>
        /// Returns the rendering object used to render the model
        /// </summary>
        public MaterialMesh MeshModel
        {
            get { return meshModel; }
        }

        /// <summary>
        /// Initialization
        /// </summary>
        protected override void OnInitialize()
        {
            base.OnInitialize();

            //create the model
            List<MaterialMesh.MaterialMeshDefinition> defs = new List<MaterialMesh.MaterialMeshDefinition>();
            foreach (SASMaterial.MaterialDefinition matOv in materials)
            {
                MaterialMesh.MaterialMeshDefinition def = new MaterialMesh.MaterialMeshDefinition()
                {
                    meshPartName = matOv.MeshPartName,
                    materialName = matOv.MaterialName,
                    diffuseMapName = matOv.DiffuseMapName,
                    normalMapName = matOv.NormalMapName,
                    specularMapName = matOv.SpecularMapName,
                    environmentMapName = matOv.EnvironmentMapName,
                    lightMapName = matOv.LightMapName
                };
                defs.Add(def);
            }

            this.meshModel = new MaterialMesh(this.meshName, layer, defs, this.ResourcePool);
            this.SceneNode.RenderGroupNames = this.RenderGroups;
            this.SceneNode.Attach(this.meshModel);

        }

        #region "Readyness"

        /// <summary>
        /// Returns true when all the resource dependant objects are ready
        /// </summary>
        protected override bool checkResourcesReady()
        {
            return base.checkResourcesReady() &&
                this.meshModel.IsReady;
        }

        #endregion

    }

}
